/**
 * 
 */
package wdmsim;

import intradomain.IntraDomainSimulator;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import multidomain.MultiDomainSimulator;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import tracing.Statistic;

/**
 * @author Andre
 *
 */
public class Simulator {

	private static final String SIMNAME = new String("wdmsim");
	private static final Float SIMVERSION = new Float(0.2);
	public static int SEED;
	public static int LOAD;
	public static boolean VERBOSE = false;
	public static boolean TRACE = false;
	//public static boolean HAS_GROOMING = false;
	//public static boolean IS_MULTIHOP = false;
	public static boolean IS_MULTIDOMAIN = false;
	public static String RWA_MODE = null;
	public static long CURRENT_TIME = 0*Constants.MILLI_SECOND;
	public static long SIMULATION_TOTAL_TIME;
	public static String TRACER_NAME;
	public static Document DOC;
	
	/**
	 * 
	 * @param simConfigFile
	 * @param trace
	 * @param verbose
	 * @param forcedLoad
	 * @param seed
	 * @throws IOException 
	 */
	public void Execute(String simConfigFile, boolean trace, String tracerName, boolean verbose, int forcedLoad, int seed, String protocol) throws IOException {
		
		VERBOSE = verbose;
		TRACE = trace;
		SEED = seed;
		LOAD = forcedLoad;
		RWA_MODE = protocol;
		
		if(trace) {
			TRACER_NAME = tracerName;
		}
		
		if (Simulator.VERBOSE) {
			System.out.println("#################################");
			System.out.println("# Simulator " + SIMNAME + " version "
					+ SIMVERSION.toString() + "  #");
			System.out.println("#################################\n");
		}
		
		try {
			
			if (Simulator.VERBOSE) {
				System.out.println("(0) Accessing simulation file "	+ simConfigFile + "...");
			}
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			DOC = docBuilder.parse(new File(simConfigFile));
			
			// normalize text representation
			DOC.getDocumentElement().normalize();

			// check the root TAG name and version
			if (!DOC.getDocumentElement().getNodeName().equals(SIMNAME)) {
				System.out.println("Root element of the simulation file is "
						+ DOC.getDocumentElement().getNodeName() + ", "
						+ SIMNAME + " is expected!");
				System.exit(0);
			}
			if (!DOC.getDocumentElement().hasAttribute("version")) {
				System.out.println("Cannot find version attribute!");
				System.exit(0);
			}
			if (Float.compare(new Float(DOC.getDocumentElement().getAttribute("version")), SIMVERSION) > 0) {
				System.out.println("Simulation config file requires a newer version of the simulator!");
				System.exit(0);
			}

			String simulationType = ((Element) DOC.getElementsByTagName("simulation-type").item(0)).getAttribute("type");
						
			if (simulationType.equalsIgnoreCase("intradomain")) {
				new IntraDomainSimulator();
			} else {
				if (simulationType.equalsIgnoreCase("multidomain")) {
					IS_MULTIDOMAIN = true;
					new MultiDomainSimulator();
				} else {
					throw new ClassNotFoundException("Class " + simulationType
							+ " of simulation type not found.");
				}
			}
			
			
		} catch (IllegalArgumentException illegalArgumentException) {
			System.err.printf("\nException: %s\n", illegalArgumentException);
			illegalArgumentException.printStackTrace();
			
		} catch (ParserConfigurationException parserConfigurationException) {
			System.err.printf("\nException: %s\n", parserConfigurationException);
			parserConfigurationException.printStackTrace();
			
		} catch (SAXException saxException) {
			System.err.printf("\nException: %s\n", saxException);
			saxException.printStackTrace();
			
		} catch (IOException ioException) {
			System.err.printf("\nException: %s\n", ioException);
			ioException.printStackTrace();
		} catch (ClassNotFoundException classNotFoundException) {
			System.err.printf("\nException: %s\n", classNotFoundException);
			classNotFoundException.printStackTrace();
		}
	}
}
